package com.imyuanma.qingyun.common.core.concurrent;


import com.imyuanma.qingyun.common.client.monitor.trace.TraceContext;
import com.imyuanma.qingyun.common.util.StringUtil;

/**
 * 抽象任务
 * 执行异步任务时推荐使用本类的实现
 *
 * @author wangjy
 * @date 2021/10/16 12:02:16
 */
public abstract class AbstractRunnable implements Runnable {
    /**
     * 日志id
     */
    protected String traceId;
    /**
     * 创建任务的主线程
     */
    protected Thread fromThread;

    public AbstractRunnable() {
        this.traceId = TraceContext.getTraceId();
        this.fromThread = Thread.currentThread();
    }

    /**
     * 执行业务
     */
    public abstract void exec();

    @Override
    public void run() {
        // 执行当前任务的线程
        Thread runThread = Thread.currentThread();
        // 如果执行任务的线程不是当初创建任务时的线程, 设置traceId, 加线程判断是为了避免线程池在走主线程执行的拒绝策略时误删traceId
        boolean dealTraceIdFlag = runThread != fromThread && StringUtil.isNotBlank(traceId);

        if (dealTraceIdFlag) {
            TraceContext.init(traceId);
        }

        try {
            // 执行任务
            exec();
        } finally {
            if (dealTraceIdFlag) {
                TraceContext.clear();
            }
        }
    }


}
